<div class="container" id="container">
  <div class="page article js_show">
    <div class="page__hd">
      <h1 class="page__title">重构实例</h1>
      <p class="page__desc">记一次复杂系统的重构实践</p>
    </div>
    <div class="page__bd">
      <article class="weui-article">
        <h1>绝知此事要躬行</h1>
        <section>
          <h2 class="title">系统背景</h2>
          <section>
            <h3>业务背景</h3>
            <p>
              一个中等复杂的业务系统，原本是购买的外包系统，但随着业务的成熟和发展，发现
              外包商对系统的升级比较缓慢，此外外包人员不稳定,之前的审批系统不能满足新的业务需要，
              重新建立一个新的自主业务系统势在必行。
            </p>
            <p>
            </p>
          </section>
          <section>
            <h3>技术背景</h3>
            <p>
              原先采用的前端页面完全由系统自动生成不利于前端开发和维护。
              所见即所得的网页开发问题在于，前端开发已经在不断变得复杂，其开发难度已经超过了
              简单的拖拽能够实现的了。虽然阿里目前也在开发基于拖拽就可以实现的前端开发体系，但是就目前来看
              开发一套所见即所得的系统的复杂度仍然太难,对一个持续变化发展的业务系统来说更难。
              因为我们都不清楚系统将会复杂到什么程度，如果我们仍然认为前端并不值得用专人维护，认为Javascript仍然是个简单的语言，那
              完全可以做这样的尝试。
              然而可以预知的是，随着分工的进一步分化，前端工程化必定会胜出，只有规范模式下的前端项目才能提供更持久的商业价值。
            </p>
          </section>
        </section>

        <section>
          <h2 class="title">2 技术选型</h2>
          <section>
            <h3>2.1 前后端分离</h3>
            <p>
              是否前后端分离的探讨，从重构的开始就在不断进行。传统的业务系统往往对前端的展示和用户体验并不关注，使用
              bootstrap之类的框架拼拼凑凑就可以搭建一个有模有样的网站。然而，随着业务逻辑的复杂化，对前端本身的要求也
              越来越高。如果前端代码被耦合在后台代码中，譬如JSP或PHP等后台语言，将导致前端的职责只能退化为提供切图和
              静态页面。代码所有权本身就存在问题，当发现问题的时候，也就无法清晰定位了。前端在前后端不分离的项目中，自身
              也因为缺乏对项目可控能力，因而缺乏主动改进和重构的可能性。对于后台来说，又觉得前端代码是由前端开发撰写，因此
              不会去持续改进了。
            </p>
            <p>
            </p>
          </section>
          <section>
            <h3>2.2 前端框架选择</h3>
            <p>
              <h4>不搞神秘主义</h4>
              框架的选择历来是很多人比较困惑的事情，大多数人会觉得前端框架只是一种个人主观选择。
              对框架选择的简单草率，导致后续的持续重构变得鸡肋。评判框架的质量的标准其实很简单，
              模块化，单一职责，可测试性，可扩展性。最流行的框架却并不一定是最好的框架，可以试着去回忆一下
              去年排行榜第一的新歌。
              <h4>决定系统质量的是人</h4>
              其实，在大多数情况下，系统的代码质量与所选的框架确实没有太多关联。
              程序员本身的技术水平，达成共识的代码规范，也许是更重要的影像因素。
              因此，我们不必过分夸大前端框架的价值和对系统的影像。在此，对前端
              框架的选择所能给予的建议是多考虑人的因素。任何前端框架都不能拿来就用，因为开源框架寻求共性但不一定适合每个公司，
              都需要前端开发人员对其进行适当改造和适配。
              前端人员的技术水平和知识结构构成应作为选择框架的首要因素，哪些框架更适合目前技术团队的整体协作和技能发挥。
              譬如我们团队中，由擅长样式和静态页面的童鞋，也有在JS方面经验更多的童鞋，选择模版和JS分离的框架更有利于
              团队的协作和优势互补。
            </p>
          </section>
        </section>

        <section>
          <h2 class="title">3 经验总结</h2>
          <section>
            <h3>3.1 文档的重要性</h3>
            <p>
              <h4>产品文档</h4>
              <p>
                无数个加班之夜，发现最需要的确认的确实产品文档问题，由于业务的确认对代码的撰写影像很大，原本以为
                加班可以解决的问题又要推迟到明天。
                关于技术的实现方案也许是技术人员自己逼自己一下就能
                解决的，关于文档问题则是相当复杂棘手了，往往是一个很小的产品需求变化就可以减去上百行代码，然而却因为业务
                人员的坚持不得不拐弯抹角得去实现。当系统出现问题的时候，又发现大家都没有足够的知识去还原原来的需求，甚至
                连原来的需求文档都找不到了，莫衷一是，模棱两可的情况下，问题自然很难很快解决了。
                为了保证系统的长期的可重构性，统一集中的产品原型维护，摈弃零散的文档组织方式是前提之一。
              </p>
            </p>
            <h3>3.1 文档的重要性</h3>
            <p>
              <h4>框架文档</h4>
              <p>
                由于框架不是完全使用的开源技术，是多个技术框架之上的封装。
                在初期阶段，由于没有足够的文档来描述和定义接口。
                很多，开发人员不清楚框架的设计理念和已经提供的公共函数，这种情况下，很多方法在应用重复实现，一些生命周期和接口函数
                没有被正确实现，这些代码零散分散在各处，对后续的改动和优化都造成巨大困难。
              </p>
            </p>
            <p>
            </p>
          </section>
          <section>
            <h3>3.2 前后端的协作</h3>
            <p>
              系统重构初期，由于前端资源紧缺，后端也要撰写前端页面。这种情况下，前端因为没有新的接口提供，工作效率无法提升。
              原本计划腾出一部分时间教会后台写前端，然而项目安排又特别紧，导致一遇到问题就需要前端立即去解决。结果是前后端的
              工作效率都无法提高。
              <p>
                后台的接口契约意识单薄，导致很多页面的接口契约迟迟无法给出，即使给出了契约，后面还会出现变动。导致已经写好的页面又要
                返工。
              </p>
            </p>
          </section>
          <section>
            <h3>3.3 统一的代码规范、代码审查的重要性</h3>
            <p>
              由于工作压力很大，又值跳槽高峰期，很多人离职。由于处在试用期，很多人的离职交接时间都很多，
              结果发现其实之前宣称完成的工作
              根本就没有完成，变量命名都是毫无语义。
              这时候别人就要把他写的七拼八凑的东西拿过来维护，不但业务逻辑要重新梳理，甚至有些代码都要重构。
            </p>
          </section>
          <section>
            <h3>3.4 重于内亦应重于外</h3>
            <p>
              由于系统重构初期，对于内部使用的系统往往并不太注重，用户体验和样式，所以对于样式和用户体验这一块没有做太多的设计。
              然而，本来认为是非主要矛盾的页面样式到后期成为很多人吐槽系统的一方面。在后来，页面展示和用户体验不够好，
              也成为系统需要采用其他框架彻底重写的理由。
            </p>
          </section>
        </section>

        <section>
          <h2 class="title">4 困惑和展望</h2>
          <section>
            <h3>4.1 前端的价值</h3>
            <p>
              从系统开始重构一直到现在，一直都存在这样的探讨，是否我们应该将前端系统的开发转给后台开发人员。
            </p><p>
              希望转给后台人员的论调认为，前端的开发流程已经相对成熟，后台同学完全可以依葫芦画瓢，对之前的页面进行维护，
              添加新的功能。后端人员对系统的底层和逻辑业务往往更熟悉，而前端人员要同时支持多个系统的前端开发，对系统的整体
              了解程度并没有后台人员深入。同一个需求要被前后端都要理解，人力资源上是重复浪费的。
            </p><p>
              不同意将前端开发移交给后台的童鞋认为，前端开发本身已经是一个智力密集型的工程化过程，只有不断维护和重构才能
              让系统有更长的成活周期，如果完全移交后台开发，系统的前端部分只会越来越糟糕，代码逐渐腐烂直到无药可救。同时，
              如果将前端开发权完全移交后台，前端对系统的掌控能力将完全被剥夺，同时系统前端出现了问题，还要专业前端人员去
              收拾烂摊子，在业务驱动的公司，前端就变成了吃力不讨好的幕后英雄了
            </p>
          </section>
          <section>
            <h3>4.2 技术栈的统一</h3>
            <p>
              技术栈的统一本是大家都想看到的事情，一直相信的是要善假于物，但不要被外物所困。对于技术框架实行拿来主义，取其精华
              去其糟粕。集百家之长，成一家之言。当听说要把系统用别的框架完全重写，其原因是为了统一技术栈。个人觉得，我们在想
              毕其功于一役，而且太孤注一掷。
              复杂问题无非是多个问题的集合：对于系统维护来说，我相信逐步重构会优于彻底重写，然而，打着统一
              技术栈的旗号来彻底重写整个系统，问题就变得复杂了。
              公司内部是否允许多技术栈的共存，如何让多个框架之间进行协作，这也许是另外一个值得探讨的问题了。
            </p>
          </section>
          <section>
            <h3>4.3 自动化测试的必要性</h3>
            <p>
              在系统技术架构设计阶段，由于错误估计了接口测试和功能测试的必要性，以至于后来发现即使想加测试用例已经不可能了。
              不管是单元测试和功能测试代码的撰写和考虑，对一个相对复杂复杂系统的长期维护和重构都具有极其重要的意义。只有
              系统具有可测试性，才能真正让开发人员睡的安心。
            </p>
          </section>
        </section>

      </article>
    </div>
    <div class="page__ft">
      <a href="javascript:home()"></a>
    </div>
  </div></div>
